package com.bestv.bsr.core.service.impl.jt.remote.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.bestv.bsr.core.context.RecommendContext;
import com.bestv.bsr.core.context.RecommendContextHolder;
import com.bestv.bsr.core.service.impl.jt.dto.response.JTSearchResponseDto;
import com.bestv.remote.context.MethodContext;
import com.bestv.remote.context.ParamContext;
import com.bestv.remote.context.ServerContext;
import com.bestv.remote.interfaces.BlockHandler;
import com.bestv.remote.interfaces.FallbackHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import static com.bestv.bsr.core.constants.CacheConstants.JT_BACK_UP;


/**
 * 九天 搜索 降级处理
 *
 * @author taojiacheng
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class JTSearchFallbackHandler implements FallbackHandler<JTSearchResponseDto>, BlockHandler<JTSearchResponseDto> {

    private final RedissonClient redissonClient;

    @Override
    public JTSearchResponseDto handlerFallback(ServerContext serverContext, MethodContext methodContext,
                                               ParamContext paramContext, Throwable throwable) {
        log.warn("九天 搜索 接口 进入降级处理流程,{},{}", serverContext, methodContext);
        return doFallBack();
    }

    @Override
    public JTSearchResponseDto handlerBlock(ServerContext serverContext, MethodContext methodContext,
                                            ParamContext paramContext, BlockException blockException) {
        log.warn("九天 搜索 接口 进入熔断处理流程,{},{}", serverContext, methodContext);
        return doFallBack();
    }

    private JTSearchResponseDto doFallBack() {
        RecommendContext recommendContext = RecommendContextHolder.getRecommendContext();
        if (recommendContext != null) {
            // todo 定时备份 ( 分布式任务 )
            String searchCacheKey = String.format(JT_BACK_UP, recommendContext.getSceneId(), "cmri_search_goodalblum");
            RBucket<JTSearchResponseDto> bucket = redissonClient.getBucket(searchCacheKey);
            JTSearchResponseDto jtSearchResponseDto = bucket.get();
            log.info("九天搜索接口, 读取缓存备份结果: {}", jtSearchResponseDto);
            return jtSearchResponseDto;
        }
        // 定时备份的情况, requestParams 为null, 不允许降级
        throw new RuntimeException("九天搜索接口备份失败");
    }


}
